<?php
/**
 * 项目默认类，此类在素玄系统内每个模块都有，供全局管理系统间握手使用
 * 
 * ============================================================================
 * 版权所有 2017北京素玄科技，并保留所有权利。
 * 
 * 网站地址: http://www.suxuantech.com
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！未经允许的情况下，您不能对本系统代码做任何修改 .
 * 不允许对程序代码以任何形式任何目的的再发布。
 * 如有修改需求，请联系素玄科技有限公司：contact@suxuantech.cn
 * ============================================================================
 * $Author: songdemei<songdemei@suxuantech.cn> 2017-10-17 $
 */
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
    function _initialize() {
        parent::_initialize();
    }

    public function index(){

        // $a = db('CustomerBase','db_sqls')->select();
        // var_dump($a);
        // exit();

        checkLogin();

        $randStr = getRandStr(10);
        session('downRand', $randStr);
        session('userId', USER_ID);
        // echo SITE_URL;        
        $urlId = input('path');
        $path = $urlId?think_decrypt($urlId):'';
        // var_dump($urlId);
        // var_dump($path);
        // exit;

        //NAV
        if($path){
            $pathArr = explode(DS, $path);
            $tmp = '';
            foreach ((array)$pathArr as $pathNav){
                if($pathNav){
                    $nav .= '<li><a href="'.url('index',['path'=>think_encrypt($tmp.DS.$pathNav)]).'">'.$pathNav.'</a></li>';
                    $tmp =$pathNav;
                }
            }
            $this->assign('nav','<li><a href="/" class="glyphicon glyphicon-home"></a></li>'.$nav);
        }

        // 从数据库获取目录地址

        $dir_path = db('c_customer')->where('id',USER_ID)->value('dir_path');
        // $folder = ROOT_PATH . $dir_path .DS.$path;
        $folder = substr($dir_path,0,2)=='//' ? $dir_path.'/'.$path : ROOT_PATH . $dir_path .DS.$path;

        if (strtoupper(substr(php_uname(),0,3)) == 'WIN') {
            $folder = iconv("UTF-8","GB2312//IGNORE",$folder);
        }
        // $folder = ROOT_PATH . config('customer_folder').  md5(USER_ID) . DS . $path;
        if(!is_dir($folder) || !file_exists($folder)){
            $this->logout();
        }
        // var_dump($path);
        // var_dump($folder);
        // exit;
        $list = scandir($folder);
        
        $fileList1 = $fileList2 = [];
        foreach ($list as $dir){
            //echo $dir;
            if(substr($dir,0,1) == '.' || $dir == 'Thumbs.db'){
            // 过虑隐藏文件或.开头的文件
                continue;
            }
            if(is_dir($folder.DS.$dir)){
                // 判断字符集
                $encode = mb_detect_encoding($dir, array("ASCII","UTF-8","GB2312","GBK","BIG5"));
                // 如果不是utf8，则转换成utf8
                if ($encode != "UTF-8"){
                    // $dir = iconv("UTF-8","GB2312//IGNORE",$dir); 
                    $dir = iconv("GBK","UTF-8",$dir); 
                }
                $fileList1[] = array('path'=>$dir,'path_en'=>  think_encrypt($path.DS.$dir),'dir'=>1);
            }else{
                // 判断字符集
                $encode = mb_detect_encoding($dir, array("ASCII","UTF-8","GB2312","GBK","BIG5"));
                // 如果不是utf8，则转换成utf8
                if ($encode != "UTF-8"){
                    // $dir = iconv("UTF-8","GB2312//IGNORE",$dir); 
                    $dir = iconv("GBK","UTF-8",$dir); 
                }
                $fileList2[] = array('path'=>$dir,'path_en'=>  think_encrypt($path.DS.$dir.$randStr),'dir'=>0);
            }
            
        }

        // exit;
        $fileList = array_merge_recursive($fileList1 , $fileList2);
        $this->assign('userInfo',  session('userInfo'));
        
        $this->assign('fileList', $fileList);
        return $this->fetch('list');
    }

    public function logout() {
        session('userInfo', null);
        header("Location: /login");
        exit();
    }

    public function download() {
        $uid = input('uid');
        $urlId = think_decrypt(input('path'));
        $downRange = session('downRand');
        if(!$downRange){
            send_http_status(404);
            exit();
        }
        $urlId = str_replace($downRange, '', $urlId);
        if ($uid) {
            $dir_path = db('c_customer')->where('id',$uid)->value('dir_path');
        }else{
            $dir_path = db('c_customer')->where('id',session('userId'))->value('dir_path');
        }
        
        // $path = ROOT_PATH.$dir_path.DS.$urlId;
        $path = substr($dir_path,0,2)=='//' ? $dir_path.'/'.$urlId : ROOT_PATH.$dir_path.DS.$urlId;

        if (strtoupper(substr(php_uname(),0,3)) == 'WIN') {
            $path = iconv("UTF-8","GB2312//IGNORE",$path);
        }
        
        // $path = ROOT_PATH . config('customer_folder').  md5(session('userId'))  . $urlId;

        //此处不需要DS了，列表页已经拼好了DS
        //$path=iconv("UTF-8","GBK",$path); 
        //$fp=  file_get_contents($path); 

        if(file_exists($path)){
            $fileinfo = pathinfo($path);
            /*
            header('Content-type: application/x-'.$fileinfo['extension']);
            header('Content-Disposition: attachment; filename='.$fileinfo['basename']);
            header('Content-Length: '.filesize($path));
            readfile($path);
            exit();
             * 
             */
            
            //*
            $fileName = substr($path, strrpos($path,DS)+1);

            header("Content-type:text/html;charset=utf-8"); 
            // $file_name="cookie.jpg"; 
            //用以解决中文不能显示出来的问题 
            // $fileName=iconv("utf-8","gb2312",$fileName);             

            $fp=fopen($path,"rb"); 
            $file_size=filesize($path); 
            
            //下载文件需要用到的头 
            Header("Content-type: application/octet-stream"); 
            Header("Accept-Ranges: bytes"); 
            Header("Accept-Length:".$file_size); 
            Header("Content-Disposition: attachment; filename=".$fileName); 
            $buffer=1024; 
            $file_count=0; 
            //向浏览器返回数据 
            //ob_start();
            while(!feof($fp) && $file_count<$file_size){
                $file_con=fread($fp,$buffer); 
                $file_count+=$buffer; 
                echo $file_con; 
                \ob_flush();  //把数据从PHP的缓冲中释放出来  
                flush();  
            } 
            fclose($fp);
            //*/
        }else{
            send_http_status(404);
            exit();
        }
    }

    // 从文件夹中打包下载
    public function downloadAll(){
        ignore_user_abort(true);
        set_time_limit(0);
        $uid  = input('uid');
        $path = think_decrypt(input('path'));

        if (!$uid || !$path) {
            $this->logout();
            exit;
        }
        // 获取用户根目录路径
        $dir_path = db('c_customer')->where('id',$uid)->value('dir_path');

        if ($dir_path === '') {
            $this->error('目标目录不存在');
            exit;
        }

        // 拼接用户要下载的目录路径
        $dir_path = substr($dir_path,0,2)=='//' ? $dir_path.$path : ROOT_PATH.$dir_path.$path;

        //最终生成的文件名
        $filename = substr($path, 1).'.zip'; 
        // 转字符集
        if (strtoupper(substr(php_uname(),0,3)) == 'WIN') {
            $filename = iconv("UTF-8","GB2312//IGNORE",$filename);
            $dir_path = iconv("UTF-8","GB2312//IGNORE",$dir_path);
        }
        // 文件目录不存在
        if(!file_exists($dir_path)){
            $this->error('目标文件不存在');
            exit;
        }
        // 生成压缩文件
        self::zipDir($dir_path, $filename);

        // 打开压缩好的文件
        $fp=fopen($filename,"rb"); 
        $file_size=filesize($filename);

        //下载文件需要用到的头 
        header("Content-type:text/html;charset=utf-8");
        header("Cache-Control: public"); 
        header("Content-Description: File Transfer"); 
        header('Content-disposition: attachment; filename='.$filename); //文件名
        header("Content-Type: application/zip"); //zip格式的
        header("Content-Transfer-Encoding: binary"); //告诉浏览器，这是二进制文件
        header('Content-Length: '. $file_size); //告诉浏览器，文件大小

        $buffer=1024; 
        $file_count=0;
        //向浏览器返回数据 
        //ob_start();
        while(!feof($fp) && $file_count<filesize($filename)){
            $file_con=fread($fp,$buffer); 
            $file_count+=$buffer; 
            echo $file_con; 
            \ob_flush();  //把数据从PHP的缓冲中释放出来  
            flush();  
        } 
        fclose($fp);

        //下载完成后删除压缩包，临时文件夹
        if($file_count >= $file_size){
            unlink($filename);
            exec("rm -rf ".$filename);
        }
    }

    /**
     * 添加文件和子目录的文件到zip文件
     * @param string $folder
     * @param ZipArchive $zipFile
     * @param int $exclusiveLength Number of text to be exclusived from the file path.
     */
    private static function folderToZip($folder, &$zipFile,$exclusiveLength) {
        $handle = opendir($folder);
        while (false !== $f = readdir($handle)) {
            if ($f != '.' && $f != '..') {
                $filePath = "$folder/$f";
                // Remove prefix from file path before add to zip.
                $localPath = substr($filePath, $exclusiveLength);
                if (is_file($filePath)) {
                    $zipFile->addFile($filePath, $localPath);
                } elseif (is_dir($filePath)) {
                    // 添加子文件夹
                    $zipFile->addEmptyDir($localPath);
                    self::folderToZip($filePath, $zipFile,$exclusiveLength);
                }
            }
        }
        closedir($handle);
    }
    /**
     * Zip a folder (include itself).
     * Usage:
     *   HZip::zipDir('/path/to/sourceDir', '/path/to/out.zip');
     *
     * @param string $sourcePath Path of directory to be zip.
     * @param string $outZipPath Path of output zip file.
     */
    public static function zipDir($sourcePath, $outZipPath) {
        $pathInfo   = self::nPathInfo($sourcePath);
        // $pathInfo   = pathinfo($sourcePath);
        $parentPath = $pathInfo['dirname'];
        $dirName    = $pathInfo['basename'];

        $sourcePath = $parentPath . '/' . $dirName; //防止传递'folder' 文件夹产生bug
        $z          = new \ZipArchive();
        $z->open($outZipPath, \ZIPARCHIVE::CREATE); //建立zip文件
        $z->addEmptyDir($dirName); //建立文件夹
        self::folderToZip($sourcePath, $z, strlen("$parentPath/"));
        $z->close();
    }

    public function login() {
        if(\think\Request::instance()->isPost()){
            $ret = array('code'=>200,'msg'=>'','data'=>array());
            $userName = input('user_name');
            $password = input('password');
            if ($password === '' || $password === false) {
                $ret['code'] = 500;
                $ret['msg'] = '密码为空，请重试';
                send_http_status(500);
                exit(json_encode($ret));
            }
            $userInfo = db('c_customer')
                    ->where('user_name',$userName)
                    ->where('password',$password)
                    ->find();
            if($userInfo){
                session('userInfo', $userInfo);
                exit(json_encode($ret));
            }else{
                $ret['code'] = 500;
                $ret['msg'] = '用户名或密码错误';
                send_http_status(500);
                exit(json_encode($ret));
            }
        }else{
            return $this->fetch();
        }
    }

    // 分享
    public function share(){
        $share_code = input('action');

        // 没有分享码
        if (!$share_code) {
            $this->logout();
            exit;
        }

        $customer = db('c_share')
                ->join('c_customer', 'c_customer.id = c_share.uid', 'left')
                ->where('c_share.share_code',  $share_code)
                ->where('c_customer.status',  1)
                ->find();

        // 用户不存在，或者禁用
        if (!$customer) {
            $this->logout();
            exit;
        }

        // 如果有密码，跳登录
        if ($customer['password'] !== '') {
            $this->logout();
            exit;
        }
        // exit;
        // 随机字符串
        $randStr = getRandStr(10);
        session('downRand', $randStr);
        // echo SITE_URL;        
        $urlId = input('path');
        $path = $urlId?think_decrypt($urlId):'';

        if($path){
            $pathArr = explode(DS, $path);
            $tmp = '';
            foreach ((array)$pathArr as $pathNav){
                if($pathNav){
                    $nav .= '<li><a href="'.url('/',['share'=>$share_code,'path'=>think_encrypt($tmp.DS.$pathNav)]).'">'.$pathNav.'</a></li>';
                    $tmp =$pathNav;
                }
            }
            $nav = '<li><a href="/share/'.$share_code.'" class="glyphicon glyphicon-home"></a></li>'.$nav;
            $this->assign('nav', $nav);
        }

        // $folder = ROOT_PATH . $customer['dir_path'] .DS.$path;
        $folder = substr($customer['dir_path'],0,2)=='//' ? $customer['dir_path'].'/'.$path : ROOT_PATH.$customer['dir_path'].DS.$path;


        if (strtoupper(substr(php_uname(),0,3)) == 'WIN') {
            $folder = iconv("UTF-8","GB2312//IGNORE",$folder);
        }
        
        if(!is_dir($folder) || !file_exists($folder)){
            $this->assign('userInfo', $customer);
            $this->assign('shareLink', '未找到您的底片'.$folder);
            $this->assign('fileList', []);
            return $this->fetch('list');
        }

        $list = scandir($folder);
        
        $fileList1 = $fileList2 = [];

        foreach ($list as $dir){
            //echo $dir;
            if(substr($dir,0,1) == '.' || $dir == 'Thumbs.db'){
            // 过虑隐藏文件或.开头的文件
                continue;
            }
            if(strpos($dir,'.rar' ) || strpos($dir,'.zip' )){
                // 过虑隐藏压缩文件
                continue;
            }

            if(is_dir($folder.DS.$dir)){
                // 判断字符集
                $encode = mb_detect_encoding($dir, array("ASCII","UTF-8","GB2312","GBK","BIG5"));
                // 如果不是utf8，则转换成utf8
                if ($encode != "UTF-8"){
                    $dir = iconv("GBK","UTF-8",$dir); 
                }
                $zipFolder = $this->getFolderZipFile($folder.DS.$this->wChange($dir));
                if($zipFolder){
                    $fileList1[] = array('path'=>$dir,'path_en'=>think_encrypt($path.DS.$dir),'dir'=>1,'down'=>think_encrypt($path.DS.$dir.DS.$zipFolder));
                }else{
                    $fileList1[] = array('path'=>$dir,'path_en'=>think_encrypt($path.DS.$dir),'dir'=>1,'down'=>'');
                }
                
            }else{
                // 判断字符集
                $encode = mb_detect_encoding($dir, array("ASCII","UTF-8","GB2312","GBK","BIG5"));
                // 如果不是utf8，则转换成utf8
                if ($encode != "UTF-8"){
                    $dir = iconv("GBK","UTF-8",$dir); 
                }
                $fileList2[] = array('path'=>$dir,'path_en'=>think_encrypt($path.DS.$dir.$randStr),'dir'=>0);
            }
            
        }
        $fileList = array_merge_recursive($fileList1 , $fileList2);

        $shareLink = config('customer_root').DS.'share'.DS.$share_code;
        $this->assign('shareLink', $shareLink);

        $this->assign('userInfo', $customer);
        $this->assign('share', $share_code);
        $this->assign('fileList', $fileList);
        return $this->fetch('list');
    }
    private function getFolderZipFile($folder){
        $list = scandir($folder);
        foreach ($list as $dir){
            
            if(strpos($dir,'.rar' ) || strpos($dir,'.zip' )){
                // 过虑隐藏压缩文件
                return $dir;
            }
        }
    }
    // 重写pathinfo函数，处理中文
    public static function nPathInfo($filepath){
        $temp = explode("\\", $filepath);
        $basename = array_pop($temp);
        $dirname = implode("\\",$temp);
        
        $final['basename'] = $basename;
        $final['dirname']  = $dirname;
        return $final; 
    }
    public function createShare(){
        if(get_client_ip() != '127.0.0.1'){
            exit('Access Denied!');
        }
        $returnData = array(
            'code' => 200,
            'msg' => '创建成功',
            'data' => [],
        );
        $customerNo = input('get.customer');
        if(empty($customerNo)){
            $returnData['code'] = 500;
            $returnData['msg'] = '无效的用户名！';
            echo json_encode($returnData);
            exit;
        }
        $folder = input('get.folder');
        $folder = $folder?$folder:date('Ym');
        $has = db('c_customer')->where(array('user_name' => $customerNo))->count();
        if ($has) {
            $returnData['code'] = 500;
            $returnData['msg'] = '用户名已经存在，请重设！';
            echo json_encode($returnData);
            exit;
        }
        $rootPath = config('customer_user');
        while (1) {
            # code...
            $str = self::myRand(10);
            $share_code = md5($rootPath).$str;
            $share_code = substr(str_shuffle($share_code), 0, 10);
            $cnt = db('c_share')->where(array('share_code' => $share_code))->count();
            if($cnt === 0){
                break;
            }
        }
        
        // 分享链接
        $share_link = config('customer_root').'/share/'.$share_code;

        if (config('sqlAddress')) {
            // 调用sqlsrv接口
            $NasUrl = urlencode($share_link);
            $url = config('sqlAddress').'Cid='.$customerNo.'&NasUrl='.$NasUrl.'&NasPwd= ';
            $sqlsrv_request = httpRequest($url, "POST" ,[], ['Content-length: 0']);
            $sqlsrv_request = json_decode($sqlsrv_request, true);

            // 判断返回值
            // if ($sqlsrv_request['ResCode'] != '0000') {
                // $this->ajaxError($sqlsrv_request['Msg']);
                // exit;
            // }else{
                // 员工自建用户根目录

            // }
        }
        $data['user_name'] = $customerNo;
        $data['password'] = '';
        $data['status'] = 1;
        $data['nickname'] = $customerNo;
        
        $data['dir_path'] = $rootPath.DS.$folder.DS.$customerNo;
        $res = db('c_customer')->insert($data);
        if($res === false){
            $returnData['code'] = 500;
            $returnData['msg'] = '创建用户失败。';
            echo json_encode($returnData);
            exit;
        }
        $uid = db('c_customer')->getLastInsID();

        // 写入分享表
        $sdata['share_code'] = $share_code;
        $sdata['uid'] = $uid;
        $res = db('c_share')->insert($sdata);
        if($res === false){
            $returnData['code'] = 500;
            $returnData['msg'] = '创建用户共享失败。';
            echo json_encode($returnData);
            exit;
        }
        echo json_encode($returnData);
        exit;
    }
    static function wChange($str){
        // 如果是windows系统，则转换字符集
        if (strtoupper(substr(php_uname(),0,3)) == 'WIN') {
            $str = iconv("UTF-8","GB2312//IGNORE",$str);
        }
        return $str;
    }
    // 随机字符串
    static function myRand($len){
        $chars='ABCDEFGHJKLMNPQRSTUVWXY1234567890abcdefghjkmnpqrstuvwxyz';
        $string=time();
        for(;$len>=1;$len--){
            $position=rand()%strlen($chars);
            $position2=rand()%strlen($string);
            $string=substr_replace($string,substr($chars,$position,1),$position2,0);
        }
        return $string;
    }
}
